package com.cx.controller.admin.basic;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.cx.base.ApiModel;
import org.cx.base.BaseController;
import org.cx.constant.BasicConstants;
import org.cx.constant.ServerCodeType;
import org.cx.entity.PageData;
import org.cx.exception.BaseException;
import org.cx.util.AssertUtil;
import org.cx.util.DesUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.cx.service.RedisService;
import com.cx.service.admin.basic.ChainBasicOrgManager;
import com.cx.service.admin.basic.ChainBasicUserManager;
import com.cx.service.admin.basic.LoginManager;
import com.cx.service.admin.outside.OutsideManager;
import com.cx.utils.MenuTreeUtil;
import com.cx.utils.RedisKeyUtil;
import com.cx.utils.SMSUtils;
import com.cx.utils.VerifyCodeUtils;


@Api(tags = "登录接口", description = "用户相关api")
@RestController("admin/basic/login")
@RequestMapping("admin/basic/login")
public class LoginController extends BaseController {

    @Resource
    private RedisService jedisService;

    @Resource
    private LoginManager loginService;

    @Resource
    private ChainBasicUserManager chainBasicUserService;

    @Resource
    private OutsideManager outsideService;

    @Resource
    private ChainBasicOrgManager chainBasicOrgService;

    @ResponseBody
    @RequestMapping(value = "/loginFlag",method = RequestMethod.POST)
    @ApiOperation(value = "判断是否已经登录", notes = "判断是否已经登录")
    @ApiImplicitParams({ 
		@ApiImplicitParam(name = "adminName", value = "用户名", required = true, dataType = "Long", paramType="query"),
		@ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "Long", paramType="query"),
		})
    public ApiModel loginFlag(HttpServletRequest request, HttpServletResponse response) throws Exception {
        PageData pd = this.getPageData();
        String token = request.getHeader("token");
        pd = jedisService.getSession(token);


        return buildSuccMsg(pd);
    }

    /**
     * 登录
     *
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/login",method = RequestMethod.POST)
    public ApiModel login(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        PageData pd = this.getPageData();
        PageData loginInfo = new PageData();
        PageData user = new PageData();
        List<PageData> allprivileges = null;
        List<PageData> privileges = new ArrayList<PageData>();//权限
        List<PageData> menu = new ArrayList<PageData>();//菜单
        List<PageData> link = new ArrayList<PageData>();//链接
        List<PageData> userlist = loginService.findUserInfoList(pd);

        AssertUtil.isTrue(userlist.size() == 1, ServerCodeType.USER_ERROR.getMessage());
        user = userlist.get(0);
        if (pd.get("loginCaptcha") != null) {
            AssertUtil.isTrue(pd.getString("loginCaptcha").toUpperCase().equals(jedisService.getSession("loginCaptcha").get("loginCaptcha")), ServerCodeType.VALIDATE_CODE_ERROR.getMessage());
        }
        AssertUtil.isTrue(DesUtils.getMD5String(pd.getString("userPwd")).equals(user.get("userPwd")), ServerCodeType.USER_PASSWORD_ERROR.getMessage());
        String token = UUID.randomUUID().toString().substring(0, 24);
        user.put("userId", user.get("id"));
        loginInfo.put("user", user);
        if (pd.get("longOnline").equals(1)) {
            setCookie(req, resp, user);
        }
        //查询菜单+权限+链接信息
        allprivileges = loginService.findUserPrivileges(user);
        if (!allprivileges.isEmpty()) {
            for (PageData data : allprivileges) {
                if (data.get("type") != null && data.get("type").equals(BasicConstants.PrivilegeType.PRIVILEGE)) {
                    privileges.add(data);
                }
                if (data.get("type") != null && data.get("type").equals(BasicConstants.PrivilegeType.MENU)) {
                    menu.add(data);
                }
                if (data.get("type") != null && data.get("type").equals(BasicConstants.PrivilegeType.LINK)) {
                    link.add(data);
                }
            }
        }

        loginInfo.put("privileges", privileges);
        loginInfo.put("menu", MenuTreeUtil.menuList(menu));
        loginInfo.put("link", MenuTreeUtil.menuList(link));
        loginInfo.put("token", token);
        jedisService.setSession(token, loginInfo);
        jedisService.setSession(RedisKeyUtil.getLoginUserKey(token), user);
        user.put("operationType", "1");//1 登录
        loginService.insertLog(user);
        return buildSuccMsg(loginInfo);
    }

    private void setCookie(HttpServletRequest req, HttpServletResponse resp, PageData user) {
        String userPhone = user.getString("userPhone");
        String userPwd = user.getString("userPwd");
        // 将用户名和密码存放在cookie对象中
        Cookie cookie = new Cookie("userInfo", userPhone + ":" + userPwd);
        // 设置有效时间三天
        cookie.setMaxAge(5 * 24 * 60 * 60);
        // 设置有效页面
        cookie.setPath("/");
        // 将cookie对象存放至response
        resp.addCookie(cookie);
    }


    /**
     * 当前用户修改密码
     *
     * @return
     * @throws Exception
     */
    @ResponseBody
    @RequestMapping(value = "/updatePassword",method = RequestMethod.POST)
    public ApiModel updatePassword(HttpServletRequest request, HttpServletResponse response) throws Exception {
        PageData pd = this.getPageData();
        PageData user = new PageData();
        PageData sessionPd = getUserByToken();
        //获取用户信息
        user.put("userPhone", sessionPd.getString("userPhone"));
        user = loginService.findUserInfo(user);
        AssertUtil.isNotNull(user, ServerCodeType.USER_NOT_FOUND.getMessage());
        System.out.println(DesUtils.getMD5String(pd.getString("oldPwd")));//96e79218965eb72c92a549dd5a330112
        AssertUtil.isTrue(DesUtils.getMD5String(pd.getString("oldPwd")).equals(user.get("userPwd")), ServerCodeType.USER_PASSWORD_ERROR.getMessage());
        AssertUtil.isTrue(pd.get("newPwd").equals(pd.get("newConfirmPwd")), ServerCodeType.CHECK_NEW_PWD.getMessage());
        user.put("userPwd", DesUtils.getMD5String(pd.getString("newPwd")));
        chainBasicUserService.updateUser(user);

        return buildSuccMsg(user);
    }

    /**
     * 登出
     *
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/exit",method = RequestMethod.POST)
    public ApiModel exit(HttpServletRequest request) {
        try {
            String token = request.getHeader("token");
            PageData admin = jedisService.getSession(token);
            if (Objects.isNull(admin)) throw BaseException.build(ServerCodeType.USER_NOT_LOGIN);
            jedisService.remove(token);
            return buildSuccMsg(null);
        } catch (Exception e) {
            return buildErrorMsg(e.getMessage());
        }
    }

    @GetMapping("/verifyCode")
    public void verifyCode(HttpServletResponse response, HttpServletRequest request) throws IOException {
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expires", 0);
        response.setContentType("image/jpeg");

        //生成随机字串
        String verifyCode = VerifyCodeUtils.generateVerifyCode(4);
        //存入会话session
        HttpSession session = request.getSession(true);
        //删除以前的
        jedisService.remove("loginCaptcha");
        PageData pd = new PageData();
        pd.put("loginCaptcha", verifyCode);
        jedisService.setSession("loginCaptcha", pd);
        jedisService.set("verifyCode",verifyCode);
        //生成图片
        int w = 100, h = 40;
        VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode);

    }


    @ResponseBody
    @RequestMapping(value = "/sendSMSForPwd",method = RequestMethod.POST)
    public ApiModel sendSMSForPwd(HttpServletResponse response, HttpServletRequest request) throws Exception {
        PageData pd = this.getPageData();
        AssertUtil.isNotNull(pd.get("userPhone"), ServerCodeType.USERPHONE_EMPTY.getMessage());
        AssertUtil.isNotNull(pd.get("verifyCode"), ServerCodeType.VALIDATE_NOT_FOUND.getMessage());
        AssertUtil.isTrue(pd.getString("verifyCode").toUpperCase().equals(jedisService.get("verifyCode")), ServerCodeType.VALIDATE_CODE_ERROR.getMessage());

        String phone = pd.getString("userPhone");
        PageData user = loginService.findUserInfo(pd);
        AssertUtil.isNotNull(user, ServerCodeType.USER_NOT_FOUND.getMessage());
        String smsCode = VerifyCodeUtils.generateNum(4);
        //存入会话session
        HttpSession session = request.getSession(true);
        //删除以前的
        jedisService.remove("smsCode");
        pd = new PageData();
        pd.put("smsCode", smsCode);
        System.out.println(smsCode);
        String validTime = "2";
        HashMap<String, Object> map = SMSUtils.sendTemplateSMS(phone, new String[]{smsCode, validTime + ""}, "8a216da85635b77e01564e4c466a0f41", "261343");
        jedisService.setSession("smsCode", pd);
        jedisService.setExpireTime("smsCode", 120L);
        return buildSuccMsg(map);
    }

    @ResponseBody
    @RequestMapping(value = "/updateForgotPassword",method = RequestMethod.POST)
    public ApiModel updateForgotPassword(HttpServletResponse response, HttpServletRequest request) throws Exception {
        PageData pd = this.getPageData();
        AssertUtil.isNotNull(pd.getString("smsCode"), ServerCodeType.VALIDATE_NOT_FOUND.getMessage());
        AssertUtil.isTrue(pd.getString("smsCode").equals(jedisService.getSession("smsCode").get("smsCode")), ServerCodeType.VALIDATE_CODE_ERROR.getMessage());
        PageData user = loginService.findUserInfo(pd);
        AssertUtil.isTrue(pd.get("newPwd").equals(pd.get("newConfirmPwd")), ServerCodeType.CHECK_NEW_PWD.getMessage());
        user.put("userPwd", DesUtils.getMD5String(pd.getString("newPwd")));
        chainBasicUserService.updateUser(user);

        return buildSuccMsg(pd);


    }


    @ResponseBody
    @RequestMapping(value = "/insertLog",method = RequestMethod.POST)
    public ApiModel insertLog() throws Exception {
        PageData pd = this.getPageData();
        PageData user = getUserByToken();
        user.put("operationType", pd.get("operationType"));
        try {
            pd = loginService.insertLog(user);
        } catch (Exception e) {
            e.printStackTrace();
            return buildErrorMsg(null, EXCEPTION, FAIL);
        }

        return buildSuccMsg(pd);
    }


}
